package io.renren.wechat.service.contact;

import com.alibaba.fastjson.JSON;
import io.renren.wechat.common.WechatResponse;
import io.renren.wechat.service.domain.*;
import io.renren.wechat.service.suite.SuiteService;
import io.renren.wechat.service.token.AccessTokenService;
import io.renren.wechat.support.ResponseEntityUtils;
import io.renren.wechat.support.WechatConstants;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 通讯录服务类
 */
@Component
public class ContactService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ContactService.class);

    private AccessTokenService accessTokenService;
    private RestTemplate fastRestTemplate;
    private SuiteService suiteService;

    /**
     * 创建成员
     *
     * @param userInfo user detail info
     * @link https://open.work.weixin.qq.com/api/doc/90000/90135/90195
     */
    public void create(String corpId, UserInfo userInfo) {
        final String accessToken = suiteService.getAuthCorpAccessToken(corpId, 0);
        String getUserDetailUrl = String.format(WechatConstants.CONTACT_CREATE_USER_URL, accessToken);

        final ResponseEntity<WechatResponse> responseEntity = fastRestTemplate.postForEntity(getUserDetailUrl, userInfo, WechatResponse.class);
        LOGGER.debug("create user response entity: {}", responseEntity);

        final WechatResponse entityBody = responseEntity.getBody();
        if (!responseEntity.getStatusCode().is2xxSuccessful() || entityBody == null) {
            LOGGER.warn("response code: {}", responseEntity.getStatusCodeValue());
            throw new RuntimeException("创建用户失败");
        }

        if (!entityBody.isSuccess()) {
            LOGGER.warn("创建用户失败, errMsg: {}", entityBody.getErrmsg());
            throw new RuntimeException("创建用户失败: " + entityBody.getErrmsg());
        }
    }

    /**
     * 更新成员
     * <p>
     * 注意，每个部门下的部门、成员总数不能超过3万个。
     *
     * @param userInfo 用户信息详情
     * @link https://open.work.weixin.qq.com/api/doc/90000/90135/90197
     */
    public void update(String corpId, UserInfo userInfo) {
        final String accessToken = suiteService.getAuthCorpAccessToken(corpId, 0);

        String updateUserDetailUrl = String.format(WechatConstants.CONTACT_UPDATE_USER_URL, accessToken);

        final ResponseEntity<WechatResponse> responseEntity = fastRestTemplate.postForEntity(updateUserDetailUrl, userInfo, WechatResponse.class);
        LOGGER.debug("update user response entity: {}", responseEntity);

        final WechatResponse entityBody = responseEntity.getBody();
        if (!responseEntity.getStatusCode().is2xxSuccessful() || entityBody == null) {
            LOGGER.warn("response code: {}", responseEntity.getStatusCodeValue());
            throw new RuntimeException("更新用户信息失败");
        }

        if (!entityBody.isSuccess()) {
            LOGGER.warn("更新用户信息失败, errMsg: {}", entityBody.getErrmsg());
            throw new RuntimeException("更新用户信息失败: " + entityBody.getErrmsg());
        }
    }

    /**
     * 读取成员
     *
     * @param userId 成员UserID。对应管理端的帐号，企业内必须唯一。不区分大小写，长度为1~64个字节
     * @return user detail info
     * @link https://open.work.weixin.qq.com/api/doc/90000/90135/90196
     */
    public UserInfo get(String corpId, String userId) {
        final String accessToken = suiteService.getAuthCorpAccessToken(corpId, 0);

        String getUserDetailUrl = String.format(WechatConstants.CONTACT_GET_USER_URL, accessToken, userId);

        LOGGER.debug("get userInfo params, accessToken: {}, userId: {}, reqUrl: {}", accessToken, userId, getUserDetailUrl);

        final ResponseEntity<UserInfo> responseEntity = fastRestTemplate.getForEntity(getUserDetailUrl, UserInfo.class);
        LOGGER.debug("get userinfo response entity: {}", responseEntity);

        final UserInfo entityBody = responseEntity.getBody();
        if (!responseEntity.getStatusCode().is2xxSuccessful() || entityBody == null) {
            LOGGER.warn("response code: {}", responseEntity.getStatusCodeValue());
            throw new RuntimeException("获取用户信息失败");
        }

        if (!entityBody.isSuccess()) {
            LOGGER.warn("获取用户信息失败, errMsg: {}", entityBody.getErrmsg());
            throw new RuntimeException("获取用户信息失败");
        }

        return entityBody;
    }

    /**
     * 获取部门成员
     *
     * @param departmentId 获取的部门id
     * @param fetchChild   是否递归获取子部门下面的成员：1-递归获取，0-只获取本部门
     * @return 部门成员列表
     */
    public List<UserSimpleInfo> getUserSimpleListInDepartment(String corpId, Integer departmentId, boolean fetchChild) {
        final String accessToken = suiteService.getAuthCorpAccessToken(corpId, 0);
        int fetchValue = fetchChild ? 1 : 0;
        String getUserListUrl = String.format(WechatConstants.CONTACT_USER_SIMPLE_LIST_URL, accessToken, departmentId, fetchValue);

        final ResponseEntity<UserSimpleInfoList> responseEntity = fastRestTemplate.getForEntity(getUserListUrl, UserSimpleInfoList.class);
        LOGGER.debug("get userSimpleList response entity: {}", responseEntity);

        final UserSimpleInfoList entityBody = responseEntity.getBody();
        if (!responseEntity.getStatusCode().is2xxSuccessful()) {
            LOGGER.warn("response code: {}", responseEntity.getStatusCodeValue());
            throw new RuntimeException("获取部门成员失败");
        }

        boolean isError = ResponseEntityUtils.isError(responseEntity)
                || entityBody == null
                || entityBody.isError();
        if (isError) {
            LOGGER.warn("获取部门成员失败");
            throw new RuntimeException("获取部门成员失败");
        }

        return entityBody.getUserlist();
    }

    /**
     * 获取部门成员详情
     * https://work.weixin.qq.com/api/doc/90001/90143/90337
     *
     * @param departmentId 获取的部门id
     * @param isFetchChild 1/0：是/否递归获取子部门下面的成员
     * @return
     */
    public List<UserInfo> getUserListInDepartment(String corpId, Integer departmentId, boolean isFetchChild) {
        final String accessToken = suiteService.getAuthCorpAccessToken(corpId, 0);
        int fetchValue = isFetchChild ? 1 : 0;
        String getUserListUrl = String.format(WechatConstants.CONTACT_USER_LIST_URL, accessToken, departmentId, fetchValue);

        LOGGER.debug("getUserListInDepartment url: {}", getUserListUrl);

        final ResponseEntity<UserInfoList> responseEntity = fastRestTemplate.getForEntity(getUserListUrl, UserInfoList.class);
        LOGGER.debug("getUserListInDepartment response entity: {}", responseEntity);

        final UserInfoList entityBody = responseEntity.getBody();
        if (!responseEntity.getStatusCode().is2xxSuccessful()) {
            LOGGER.warn("response code: {}", responseEntity.getStatusCodeValue());
            throw new RuntimeException("获取部门成员详情失败");
        }

        if (entityBody == null) {
            LOGGER.warn("getUserListInDepartment failed, response body is empty!");
            throw new RuntimeException("获取 getUserListInDepartment 失败，响应为空");
        }

        boolean isError = ResponseEntityUtils.isError(responseEntity) || entityBody.isError();
        if (isError) {
            LOGGER.warn("获取部门成员详情失败");
            throw new RuntimeException("获取部门成员详情失败");
        }

        return entityBody.getUserlist();
    }

    /**
     * 删除成员
     *
     * @param userId 对应管理端的帐号
     * @link https://open.work.weixin.qq.com/api/doc/90000/90135/90198
     */
    public boolean deleteUser(String corpId, String userId) {
        final String accessToken = suiteService.getAuthCorpAccessToken(corpId, 0);
        String getUserListUrl = String.format(WechatConstants.CONTACT_DELETE_USER_URL, accessToken, userId);

        final ResponseEntity<WechatResponse> responseEntity = fastRestTemplate.getForEntity(getUserListUrl, WechatResponse.class);
        LOGGER.debug("delete user response entity: {}", responseEntity);

        if (!responseEntity.getStatusCode().is2xxSuccessful()) {
            LOGGER.warn("response code: {}", responseEntity.getStatusCodeValue());
            throw new RuntimeException("删除成员失败");
        }

        final WechatResponse body = responseEntity.getBody();
        if (null == body) {
            LOGGER.warn("delete user response body is empty!");
            return false;
        }
        if (!body.isSuccess()) {
            LOGGER.warn("delete user failed, errMsg: {}", body.getErrmsg());
        }

        return body.isSuccess();
    }

    /**
     * 批量删除成员
     *
     * @param userIdList 成员UserID列表。对应管理端的帐号。最多支持200个。若存在无效UserID，直接返回错误
     * @link https://open.work.weixin.qq.com/api/doc/90000/90135/90199
     */
    public boolean batchDeleteUser(String corpId, List<String> userIdList) {
        final String accessToken = suiteService.getAuthCorpAccessToken(corpId, 0);

        String getUserListUrl = String.format(WechatConstants.CONTACT_BATCH_DELETE_USER_URL, accessToken);
        if (CollectionUtils.isEmpty(userIdList)) {
            LOGGER.warn("batch delete userId list is empty!!!");
            return true;
        }

        Map<String, Object> params = new HashMap<>();
        params.put("useridlist", userIdList);

        final ResponseEntity<WechatResponse> responseEntity = fastRestTemplate.postForEntity(getUserListUrl, params, WechatResponse.class);
        LOGGER.debug("batch delete users response entity: {}", responseEntity);

        if (!responseEntity.getStatusCode().is2xxSuccessful()) {
            LOGGER.warn("response code: {}", responseEntity.getStatusCodeValue());
            throw new RuntimeException("批量删除成员失败");
        }

        final WechatResponse body = responseEntity.getBody();
        if (null == body) {
            LOGGER.warn("batch delete user response body is empty!");
            return false;
        }
        if (!body.isSuccess()) {
            LOGGER.warn("batch delete user failed, errMsg: {}", body.getErrmsg());
        }

        return body.isSuccess();
    }

    /**
     * userid与openid互换
     *
     * @param userId 企业内的成员id
     * @return 企业微信成员userid对应的openid
     */
    public String getOpenId(String corpId, String userId) {
        final String accessToken = suiteService.getAuthCorpAccessToken(corpId, 0);
        String getUserListUrl = String.format(WechatConstants.CONTACT_GET_OPENID_URL, accessToken);
        if (StringUtils.isBlank(userId)) {
            LOGGER.warn("get openId userId can not be blank!!!");
            throw new IllegalArgumentException("userId is required!!!");
        }

        Map<String, Object> params = new HashMap<>();
        params.put("userid", userId);

        final ResponseEntity<OpenId> responseEntity = fastRestTemplate.postForEntity(getUserListUrl, params, OpenId.class);
        LOGGER.debug("get openid response entity: {}", responseEntity);

        if (!responseEntity.getStatusCode().is2xxSuccessful()) {
            LOGGER.warn("response code: {}", responseEntity.getStatusCodeValue());
            throw new RuntimeException("userid转openid失败");
        }

        final OpenId body = responseEntity.getBody();
        if (null == body) {
            LOGGER.warn("get openId response body is empty!");
            throw new RuntimeException("userid转openid失败");
        }
        if (!body.isSuccess()) {
            LOGGER.warn("get openId failed, errMsg: {}", body.getErrmsg());
        }

        return body.getOpenid();
    }


    @Autowired
    public void setAccessTokenService(AccessTokenService accessTokenService) {
        this.accessTokenService = accessTokenService;
    }

    @Autowired
    public void setFastRestTemplate(RestTemplate fastRestTemplate) {
        this.fastRestTemplate = fastRestTemplate;
    }

    @Autowired
    public void setSuiteService(SuiteService suiteService) {
        this.suiteService = suiteService;
    }

    public static void main(String[] args) {
        final UserInfoList userInfoList = JSON.parseObject("{\"errcode\":0,\"errmsg\":\"ok\",\"userlist\":[{\"userid\":\"ChenLinJun\",\"name\":\"ChenLinJun\",\"department\":[1],\"gender\":\"1\",\"avatar\":\"https://rescdn.qqmail.com/node/wwmng/wwmng/style/images/independent/DefaultAvatar$73ba92b5.png\",\"status\":1,\"order\":[0],\"main_department\":1,\"is_leader_in_dept\":[],\"thumb_avatar\":\"https://rescdn.qqmail.com/node/wwmng/wwmng/style/images/independent/DefaultAvatar$73ba92b5.png\",\"open_userid\":\"woE44jCAAAxiHcKvLrfhP8f0h2WESbhQ\",\"direct_leader\":[]},{\"userid\":\"HaiLiBu\",\"name\":\"HaiLiBu\",\"department\":[1],\"gender\":\"1\",\"avatar\":\"https://rescdn.qqmail.com/node/wwmng/wwmng/style/images/independent/DefaultAvatar$73ba92b5.png\",\"status\":1,\"order\":[0],\"main_department\":1,\"is_leader_in_dept\":[],\"thumb_avatar\":\"https://rescdn.qqmail.com/node/wwmng/wwmng/style/images/independent/DefaultAvatar$73ba92b5.png\",\"open_userid\":\"woE44jCAAA2wCu3GouoBoJl017ynNbAQ\",\"direct_leader\":[]},{\"userid\":\"ZiJiXieZong\",\"name\":\"ZiJiXieZong\",\"department\":[1],\"gender\":\"1\",\"avatar\":\"https://rescdn.qqmail.com/node/wwmng/wwmng/style/images/independent/DefaultAvatar$73ba92b5.png\",\"status\":1,\"order\":[0],\"main_department\":1,\"is_leader_in_dept\":[],\"thumb_avatar\":\"https://rescdn.qqmail.com/node/wwmng/wwmng/style/images/independent/DefaultAvatar$73ba92b5.png\",\"open_userid\":\"woE44jCAAAty_VAlQjIs3Yr_Gc5xM5CA\",\"direct_leader\":[]}]}", UserInfoList.class);

        System.out.println(userInfoList);
    }
}
